<template>
  <div class="user_box" v-loading="loading">
    <div class="user_addbtn">
      <el-button icon="plus" @click="openAddDialog()" type="primary">
        新增用户
      </el-button>
    </div>
    <el-table
      :data="userDatas?.list"
      row-key="id"
      border
      :header-row-style="{ color: '#232324', fontWeight: 'bold' }"
    >
      <el-table-column align="center" label="ID" min-width="50" prop="id" />
      <el-table-column align="center" label="头像" min-width="70">
        <template #default="scope">
          <el-avatar :size="38" :src="scope.row.avatar" />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="用户名"
        min-width="120"
        prop="username"
      />
      <el-table-column
        align="center"
        label="真实姓名"
        min-width="120"
        prop="name"
      />
      <el-table-column align="center" label="性别" min-width="75">
        <template #default="scope">
          <span v-if="scope.row.sex == 1">男</span>
          <span v-else>女</span>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="邮箱"
        min-width="200"
        prop="email"
      />
      <el-table-column align="center" label="角色" min-width="210">
        <template #default="scope">
          <el-cascader
            v-model="scope.row.roleIds"
            :options="roleOptions"
            :show-all-levels="false"
            collapse-tags
            :props="{
              multiple: true,
              checkStrictly: true,
              label: 'name',
              value: 'id',
              emitPath: false,
            }"
            :clearable="false"
            @visible-change="
              (flag) => {
                changeRole(scope.row, flag, 0)
              }
            "
            @remove-tag="
              (val) => {
                changeRole(scope.row, false, val)
              }
            "
          />
        </template>
      </el-table-column>
      <el-table-column align="center" label="状态" min-width="75">
        <template #default="scope">
          <el-tag v-if="scope.row.status == 1" type="success">正常</el-tag>
          <el-tag v-else type="danger">停用</el-tag>
        </template>
      </el-table-column>
      <!-- <el-table-column align="center" label="逻辑删除" min-width="100">
        <template #default="scope">
          <el-tag v-if="scope.row.deleted == 1" type="danger">已删除</el-tag>
          <el-tag v-else type="success">使用中</el-tag>
        </template>
      </el-table-column> -->
      <el-table-column
        align="center"
        label="创建时间"
        min-width="180"
        prop="createTime"
      />
      <el-table-column
        align="center"
        label="更新时间"
        min-width="180"
        prop="updateTime"
      />
      <el-table-column align="center" fixed="right" label="操作" width="300">
        <template #default="scope">
          <el-button
            type="primary"
            link
            icon="edit"
            @click="openEditDialog(scope.row)"
          >
            编辑
          </el-button>
          <el-popconfirm
            :icon="InfoFilled"
            icon-color="#626AEF"
            width="180"
            title="是否删除该用户?"
            @confirm="deleteUserById(scope.row.id)"
          >
            <template #reference>
              <el-button type="primary" link icon="delete">删除</el-button>
            </template>
          </el-popconfirm>
          <el-popconfirm
            :icon="InfoFilled"
            icon-color="#626AEF"
            width="180"
            title="是否重置密码为123456?"
            @confirm="resetUserPwd(scope.row.id)"
          >
            <template #reference>
              <el-button type="primary" link icon="magic-stick">
                重置密码
              </el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      style="margin-top: 12px"
      v-model:current-page="userPageParmas.pageNum"
      v-model:page-size="userPageParmas.pageSize"
      :page-sizes="[10, 20, 40]"
      :background="true"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <el-dialog
      v-model="dialogFormVisible"
      :title="dialogTitle"
      style="min-width: 400px"
    >
      <el-form
        v-if="dialogFormVisible"
        ref="userForms"
        :inline="true"
        :model="userForm"
        :rules="rules"
        label-position="top"
        label-width="85px"
      >
        <el-form-item label="用户名username" prop="username" style="width: 40%">
          <el-input v-model="userForm.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item
          v-if="!isEdit"
          prop="password"
          label="密码password"
          style="width: 40%"
          required
        >
          <el-input
            v-model="userForm.password"
            placeholder="用户密码"
            type="password"
            show-password
          />
        </el-form-item>
        <el-form-item label="真实姓名" prop="name" style="width: 40%">
          <el-input
            v-model="userForm.name"
            placeholder="请输入用户的真实姓名"
          />
        </el-form-item>
        <el-form-item label="性别" prop="sex" style="width: 40%">
          <el-select v-model="userForm.sex" placeholder="用户的性别">
            <el-option :value="1" label="男" />
            <el-option :value="2" label="女" />
          </el-select>
        </el-form-item>
        <el-form-item label="邮箱" prop="email" style="width: 40%">
          <el-input v-model="userForm.email" type="email" />
        </el-form-item>
        <el-form-item label="头像" prop="type" style="width: 40%">
          <el-upload
            class="avatar-uploader"
            :action="Upload_API.IMAGE_URL"
            :headers="headerObj"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="userForm.avatar" :src="userForm.avatar" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="个性签名" prop="sign" style="width: 50%">
          <el-input
            v-model="userForm.sign"
            placeholder="请输入用户的个性签名"
            maxlength="50"
            show-word-limit
            type="textarea"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="formConfirm(userForms)">
            提交
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import {
  reqAddUser,
  reqDeleteUser,
  reqDeleteUserRole,
  reqResetPwd,
  reqResetUserRole,
  reqUpdateUserInfo,
  reqUserInfoPage,
} from '@/api/user'
import {
  AddUserParams,
  UserInfoPageParams,
  UserInfoRes,
  UserPageRes,
  UserRolesParams,
} from '@/api/user/type'
import { ElMessage } from 'element-plus'
import { InfoFilled } from '@element-plus/icons-vue'
import type { FormInstance, UploadProps } from 'element-plus'
import { Upload_API } from '@/api/upload'
import { GET_TOKEN } from '@/utils/token'
import { UploadImageRes } from '@/api/upload/type'
import { reqRoleOptions } from '@/api/role'

onMounted(async () => {
  await getUserInfoPage()
  await getRoleOptions()
})

const dialogFormVisible = ref<boolean>(false)
const userPageParmas: UserInfoPageParams = reactive({
  pageNum: 1,
  pageSize: 10,
})
const userDatas = ref<UserPageRes>()
const total = ref(0)
const loading = ref(false)
const roleOptions = ref()

const userForms = ref<FormInstance>()
let userForm: AddUserParams = reactive({
  id: 0,
  username: '',
  password: '',
  avatar: '',
  email: '',
  name: '',
  sex: 1,
  sign: '',
})

const rules = reactive({
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  name: [{ required: true, message: '请输入真实姓名', trigger: 'blur' }],
  sex: [{ required: true, message: '请选择性别', trigger: 'blur' }],
})

const headerObj = {
  Authorization: GET_TOKEN(),
}

// 添加菜单方法，id为 0则为添加根菜单
const dialogTitle = ref('新增用户')
const isEdit = ref(false)

const getUserInfoPage = async () => {
  loading.value = true
  try {
    const { data } = await reqUserInfoPage(userPageParmas)
    userDatas.value = data
    total.value = data.total
  } catch (error) {
    if (error instanceof Error) {
      ElMessage.error(error.message)
    }
  } finally {
    loading.value = false
  }
}

const getRoleOptions = async () => {
  try {
    const { data } = await reqRoleOptions()
    roleOptions.value = data
  } catch (error) {
    if (error instanceof Error) {
      ElMessage.error(error.message)
    }
  }
}

const deleteUserById = async (id: number) => {
  try {
    const { message } = await reqDeleteUser(id)
    ElMessage.success(message)
    await getUserInfoPage()
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const resetUserPwd = async (id: number) => {
  try {
    const { message } = await reqResetPwd(id)
    ElMessage.success(message)
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const addUser = async () => {
  try {
    const { message } = await reqAddUser(userForm)
    ElMessage.success(message)
    userForm = {
      username: '',
      password: '',
      avatar: '',
      email: '',
      name: '',
      sex: 1,
      sign: '',
    }
    await getUserInfoPage()
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const updateUser = async () => {
  try {
    const { message } = await reqUpdateUserInfo(userForm)
    ElMessage.success(message)
    await getUserInfoPage()
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const formConfirm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid) => {
    if (valid) {
      if (isEdit.value) {
        updateUser()
      } else {
        addUser()
      }
      dialogFormVisible.value = false
    }
  })
}

const openAddDialog = () => {
  isEdit.value = false
  if (userForm.id !== 0) {
    userForm = {
      username: '',
      password: '',
      avatar: '',
      email: '',
      name: '',
      sex: 1,
      sign: '',
    }
  }
  dialogTitle.value = '新增用户'
  dialogFormVisible.value = true
}
// 修改菜单方法
const openEditDialog = async (data: UserInfoRes) => {
  isEdit.value = true
  dialogTitle.value = '编辑用户'
  userForm.avatar = data.avatar
  userForm.id = data.id
  userForm.username = data.username
  userForm.email = data.email
  userForm.name = data.name
  userForm.sex = data.sex
  userForm.sign = data.sign
  dialogFormVisible.value = true
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
  const data: UploadImageRes = response.data
  userForm.avatar = data.imageUrl
}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
    ElMessage.error('上传的图片格式必须是png或jpg！')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2MB！')
    return false
  }
  return true
}

const handleSizeChange = (val: number) => {
  getUserInfoPage()
}
const handleCurrentChange = (val: number) => {
  getUserInfoPage()
}

const changeRole = async (row: UserInfoRes, flag: boolean, val: any) => {
  if (!flag) {
    if (val === 0) {
      const userRoles: UserRolesParams = {
        userId: row.id,
        roleIds: row.roleIds,
      }
      try {
        const { message } = await reqResetUserRole(userRoles)
        ElMessage.success(message)
      } catch (error) {
        ElMessage.error((error as Error).message)
      }
    } else {
      const userRoles: UserRolesParams = {
        userId: row.id,
        roleIds: [val],
      }
      try {
        const { message } = await reqDeleteUserRole(userRoles)
        ElMessage.success(message)
      } catch (error) {
        ElMessage.error((error as Error).message)
      }
    }
  }
}
</script>
<style scoped lang="scss">
.user_box {
  padding: 24px;

  .user_addbtn {
    margin-bottom: 12px;
    display: flex;
  }

  .icon-column {
    display: flex;
    align-items: center;

    .el-icon {
      margin-right: 8px;
    }
  }
}

.avatar-uploader .avatar {
  width: 128px;
  height: 128px;
  display: block;
}
</style>

<style lang="scss">
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 128px;
  height: 128px;
  text-align: center;
}
</style>
